package org.qq.tv.web.service;

import org.qq.tv.web.mapper.InsertWebDate;
import org.qq.tv.web.mapper.SelectWebDate;
import org.qq.tv.web.mapper.pojo.task.UpTaskDate;
import org.qq.tv.web.task.TaskNet;
import org.qq.tv.web.task.TaskSql;
import org.qq.tv.web.tools.HttpComNet;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

/*
 *   网站更新数据服务
 *
 *
 */

@Service
public class UpDateService {
    // 数据库单线程 线程池
    private final ExecutorService exeSql;//线程池
    //任务队列 保函线程安全
    private final List<UpTaskDate> sqltask = Collections.synchronizedList(new ArrayList<>());
    private final int sqlsize;//数据库任务最高数量
    // 联网线程池 多线程执行
    private final ExecutorService exeNet;//线程池
    private final List<UpTaskDate> nettask = Collections.synchronizedList(new ArrayList<>());
    private final int netsize;//联网任务最高数量
    // 联网 浏览器
    private final HttpComNet http;
    /*
     * 提交数据库任务
     *
     */
    public String sqlTasktyep = null;
    /*
     * 提交网络任务任务
     *
     */
    public String netTasktyep = null;
    private int sqlcont = 0;//数据库任务数量
    private int netcont = 0;//联网任务数量
    @Autowired
    private InsertWebDate insert;//数据库添加工具
    @Autowired
    private SelectWebDate select;//数据库查询工具

    public UpDateService() {
        this.http = new HttpComNet();
        this.exeSql = Executors.newSingleThreadScheduledExecutor();
        this.exeNet = Executors.newFixedThreadPool(32);
        this.netsize = 1024;
        this.sqlsize = 512;

    }

    public synchronized boolean submitSql(UpTaskDate date) {
        // OutUpDate.out(date);
        this.sqlTasktyep = "任务队列 = " + this.sqltask.size() + " = 数据库任务数量 = " + this.sqlcont + "任务类型 = " + date.getTaskTyep();
        //任务数据空直接返回
        if (date == null) return false;
        //判断任务是否满
        if (this.startStopSql(true) == false) {
            //数据库任务满就添加到任务队列去
            this.sqltask.add(date);
            return false;
        }
        //执行任务
        // new TaskSql(this,date).run();

        this.exeSql.submit(new TaskSql(this, date));
        return true;
    }

    public synchronized boolean submitNet(UpTaskDate date) {
        this.netTasktyep = "任务队列 = " + this.nettask.size() + " = 联网任务数量 = " + this.netcont + "任务类型 = " + date.getTaskTyep();
        //System.out.println("联网任务数量 = "+this.netcont+"任务类型 = "+date.getTaskTyep());
        //任务数据空直接返回
        if (date == null) return false;
        //判断任务是否满
        if (this.startStopNet(true) == false) {
            //网络任务满就添加到任务队列去
            this.nettask.add(date);
            return false;
        }
        //执行任务
        //new TaskNet(this,date).run();
        this.exeSql.submit(new TaskNet(this, date));
        return true;
    }


    /**
     * 数据库 任务 开始结束调用
     * task true 开始 false 结束
     *
     * @param task
     * @return
     */
    public final synchronized boolean startStopSql(boolean task) {
        //任务开始
        if (task) {
            //判断任务是否满要是满了就休息 5秒
            if (this.sqlsize <= this.sqlcont) {
                return false;
            }
            this.sqlcont++;
            return true;
        }

        if (0 < this.sqlcont) {

            //释放任务数量
            this.sqlcont--;
            //System.out.println("数据库任务完成 =   "+this.sqlcont);
            //  System.out.println("数据库任务队列 = "+this.sqltask.size());
            int sqllsize = this.sqltask.size() - 1;
            if (sqllsize != -1 && this.sqlcont < this.sqlsize) {
                UpTaskDate date = this.sqltask.remove(sqllsize);
                this.submitSql(date);

            }
        }
        return true;
    }

    /*
     * 联网 任务 开始结束调用
     * task true 开始 false 结束
     */
    public final synchronized boolean startStopNet(boolean task) {
        //任务开始
        if (task) {
            //判断任务是否满要是满了就休息 5秒
            if (this.netsize <= this.netcont) {
                //休息 秒
                // Thread.sleep(5000);
                return false;
            }
            this.netcont++;
            return true;
        }
        if (task == false) {
            if (0 < this.netcont) {
                //释放任务数量
                this.netcont--;
                //System.out.println("联网任务完成  =   "+this.netcont);
                // System.out.println("联网任务队列  =   "+this.sqltask.size());
                int netlsize = this.nettask.size() - 1;
                if (netlsize != -1 && this.netcont < this.netsize) {

                    UpTaskDate date = this.nettask.remove(netlsize);
                    this.submitNet(date);
                }
            }
            //System.out.println("联网任务完成  =   "+this.netcont);
            return true;
        }


        return true;
    }

    public ExecutorService getExeSql() {
        return exeSql;
    }

    public List<UpTaskDate> getSqltask() {
        return sqltask;
    }

    public int getSqlsize() {
        return sqlsize;
    }

    public int getSqlcont() {
        return sqlcont;
    }

    public void setSqlcont(int sqlcont) {
        this.sqlcont = sqlcont;
    }

    public ExecutorService getExeNet() {
        return exeNet;
    }

    public List<UpTaskDate> getNettask() {
        return nettask;
    }

    public int getNetsize() {
        return netsize;
    }

    public int getNetcont() {
        return netcont;
    }

    public void setNetcont(int netcont) {
        this.netcont = netcont;
    }

    public InsertWebDate getInsert() {
        return insert;
    }

    public void setInsert(InsertWebDate insert) {
        this.insert = insert;
    }

    public SelectWebDate getSelect() {
        return select;
    }

    public void setSelect(SelectWebDate select) {
        this.select = select;
    }

    public HttpComNet getHttp() {
        return http;
    }

    public String getSqlTasktyep() {
        return sqlTasktyep;
    }

    public void setSqlTasktyep(String sqlTasktyep) {
        this.sqlTasktyep = sqlTasktyep;
    }

    public String getNetTasktyep() {
        return netTasktyep;
    }

    public void setNetTasktyep(String netTasktyep) {
        this.netTasktyep = netTasktyep;
    }
}
